package cn.com.ctbri.geomonitor.service.impl;

import java.awt.print.PrinterAbortException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.management.loading.PrivateClassLoader;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.Spring;
import javax.swing.UnsupportedLookAndFeelException;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.aspectj.asm.internal.ProgramElement;
import org.aspectj.weaver.ast.Var;

import cn.com.ctbri.geomonitor.model.ProXuanZhi;
import cn.com.ctbri.geomonitor.model.ProXuanZhiExample;
import cn.com.ctbri.geomonitor.model.Program;
import cn.com.ctbri.geomonitor.model.ProgramExample;
import cn.com.ctbri.geomonitor.model.Vacation;
import cn.com.ctbri.geomonitor.model.VacationExample;
import cn.com.ctbri.geomonitor.utils.DateUtil;
import cn.com.ctbri.geomonitor.bean.BaseForm;
import cn.com.ctbri.geomonitor.bean.CommentVO;
import cn.com.ctbri.geomonitor.bean.FormField;
import cn.com.ctbri.geomonitor.bean.ProXuanZhiForm;
import cn.com.ctbri.geomonitor.bean.ProcessVO;
import cn.com.ctbri.geomonitor.bean.TaskVO;
import cn.com.ctbri.geomonitor.bean.VacationForm;
import cn.com.ctbri.geomonitor.bean.departmentTask;
import cn.com.ctbri.geomonitor.dao.ProXuanZhiMapper;
import cn.com.ctbri.geomonitor.dao.ProgramMapper;
import cn.com.ctbri.geomonitor.dao.VacationMapper;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ser.std.UUIDSerializer;
import com.mysql.fabric.ShardingType;
import com.mysql.fabric.xmlrpc.base.Data;
import com.sun.mail.handlers.image_gif;

import cn.com.ctbri.geomonitor.service.ProcessRestService;

@Service("processRestService")
public class ProcessRestSreviceImpl implements ProcessRestService {

	@Resource(name = "runtimeService")
	private RuntimeService runtimeService;

	@Resource(name = "historyService")
	private HistoryService historyService;

	@Resource(name = "repositoryService")
	private RepositoryService repositoryService;

	@Resource(name = "identityService")
	private IdentityService identityService;

	@Resource(name = "taskService")
	private TaskService taskService;

	@Resource(name = "processEngine")
	private ProcessEngine processEngine;

	@Resource(name = "vacationMapper")
	private VacationMapper vacationMapper = null;

	@Resource(name = "proXuanZhiMapper")
	private ProXuanZhiMapper proXuanZhiMapper = null;

	@Resource(name = "programMapper")
	private ProgramMapper programMapper = null;

	/*
	 * 启动请假申请 public ProcessInstance startVacation(VacationForm vacation,
	 * MultipartFile[] file, HttpServletRequest request) { // 设置标题
	 * vacation.setTitle(vacation.getUserName() + " 的请假申请");
	 * vacation.setBusinessType("请假申请"); // 查找流程定义 ProcessDefinition pd =
	 * repositoryService.createProcessDefinitionQuery().processDefinitionKey(
	 * "Vacation") .singleResult(); // 初始化任务参数 Map<String, Object> vars = new
	 * HashMap<String, Object>(); vars.put("arg", vacation); // 启动流程
	 * ProcessInstance pi =
	 * this.runtimeService.startProcessInstanceByKey(pd.getKey()); // 查询第一个任务
	 * Task firstTask =
	 * this.taskService.createTaskQuery().processInstanceId(pi.getId()).
	 * singleResult(); // 设置任务受理人 taskService.setAssignee(firstTask.getId(),
	 * vacation.getUserId());
	 * 
	 * // 记录请假数据 saveVacation(vacation, pi.getId());
	 * 
	 * List<String> urls = uploadAttachment(file, request); for (int i = 0; i <
	 * urls.size(); i++) { String filename = file[i].getOriginalFilename();
	 * String url = urls.get(i); // 给流程添加附件 taskService.createAttachment("",
	 * firstTask.getId(), pi.getId(), filename, "", url); }
	 * 
	 * // 完成任务 taskService.complete(firstTask.getId(), vars);
	 * 
	 * return pi; }
	 * 
	 * // 启动项目选址意见书
	 * 
	 * @Override public ProcessInstance startProXuanZhi(MultipartFile[] file,
	 * ProXuanZhiForm proXuanZhiForm, HttpServletRequest request) { // 设置标题
	 * proXuanZhiForm.setTitle(proXuanZhiForm.getUserName() + " 的项目选址意见书申请");
	 * proXuanZhiForm.setBusinessType("项目选址意见书申请"); // 查找流程定义 ProcessDefinition
	 * pd =
	 * repositoryService.createProcessDefinitionQuery().processDefinitionKey(
	 * "ProXuanZhi") .singleResult(); // 初始化任务参数 Map<String, Object> vars = new
	 * HashMap<String, Object>(); vars.put("arg", proXuanZhiForm); // 启动流程
	 * ProcessInstance pi =
	 * this.runtimeService.startProcessInstanceByKey(pd.getKey()); // 查询第一个任务
	 * Task firstTask =
	 * this.taskService.createTaskQuery().processInstanceId(pi.getId()).
	 * singleResult(); // 设置任务受理人 taskService.setAssignee(firstTask.getId(),
	 * proXuanZhiForm.getUserId());
	 * 
	 * // 记录请假数据 saveProXuanZhi(proXuanZhiForm, pi.getId());
	 * 
	 * List<String> urls = uploadAttachment(file, request); for (int i = 0; i <
	 * urls.size(); i++) { String filename = file[i].getOriginalFilename();
	 * String url = urls.get(i); // 给流程添加附件 taskService.createAttachment("",
	 * firstTask.getId(), pi.getId(), filename, "", url); }
	 * 
	 * // 完成任务 taskService.complete(firstTask.getId(), vars);
	 * 
	 * return pi; }
	 */
	// 文件上传
	private List<String> uploadAttachment(MultipartFile[] file, HttpServletRequest request, String type, String userID,
			String programName,String pi) {

		List<String> imgUrlList = new ArrayList<String>();
		// 判断apiImages数组不能为空并且长度大于0
		if (file != null && file.length > 0) {

			// 循环获取apiImages数组中得文件
			for (int i = 0; i < file.length; i++) {
				MultipartFile apiImgFile = file[i];
				// 文件保存路径
				String imgPath = request.getSession().getServletContext().getRealPath("upload") + "/" + type + "/"
						+ userID + "/" + programName+"/"+pi;
				String imgFileName = apiImgFile.getOriginalFilename();
				// 目标文件
				File imgFile = new File(imgPath, imgFileName);
				// 图片保存目录
				File picDir = new File(imgPath);
				// 如果目录不存在就创建目录
				if (!picDir.exists() && !picDir.isDirectory()) {
					picDir.mkdirs();
				}
				// 保存文件
				if (saveFile(apiImgFile, imgFile)) {

					imgUrlList.add("upload/" + type + "/" + userID + "/" + programName  +"/"+pi+"/" + imgFileName);

				}
			}

		}
		return imgUrlList;
	}

	// 将一条请假申请保存到OA_VACATION表中
	private void saveVacation(VacationForm vacForm, String piId) {
		Vacation vac = new Vacation();
		vac.setBeginDate(DateUtil.getDate(vacForm.getStartDate()));
		vac.setWorkDays(vacForm.getDays());
		vac.setEndDate(DateUtil.getDate(vacForm.getEndDate()));
		vac.setProcInstId(piId);
		vac.setReason(vacForm.getReason());
		vac.setVacType(vacForm.getVacationType());
		vac.setUserId(vacForm.getUserId());
		int result = vacationMapper.insert(vac);
		if (result == 1) {
			System.out.println("插入成功");
		}
	}

	// 将一条申请保存到OA_ProXuanZhi表中
	private void saveProXuanZhi(ProXuanZhiForm proXuanZhiForm, String piId) {
		ProXuanZhi proXuanZhi = new ProXuanZhi();
		proXuanZhi.setProcInstId(piId);
		proXuanZhi.setType(proXuanZhiForm.getType());
		proXuanZhi.setUserId(proXuanZhiForm.getUserId());
		int result = proXuanZhiMapper.insert(proXuanZhi);
		if (result == 1) {
			System.out.println("插入成功");
		}
	}

	// 查询请假申请
	public List<ProcessVO> listVacation(String userId) {
		// 查询OA_VACATION表的数据
		VacationExample example = new VacationExample();
		example.createCriteria().andUserIdEqualTo(userId);
		List<Vacation> vacs = vacationMapper.selectByExample(example);
		List<ProcessVO> result = new ArrayList<ProcessVO>();
		for (Vacation vac : vacs) {
			// 查询流程实例
			ProcessInstance pi = this.runtimeService.createProcessInstanceQuery().processInstanceId(vac.getProcInstId())
					.singleResult();
			if (pi != null) {
				// 查询流程参数
				BaseForm var = (BaseForm) this.runtimeService.getVariable(pi.getId(), "arg");
				// 封装界面对象
				ProcessVO vo = new ProcessVO();
				vo.setTitle(var.getTitle());
				vo.setRequestDate(var.getRequestDate());
				vo.setId(pi.getId());
				System.out.println(vo.getTitle());
				System.out.println(vo.getRequestDate());
				result.add(vo);
			}
		}
		return result;
	}

	// 查询项目选址意见书申请
	@Override
	public List<ProcessVO> listProXuanZhi(String userId) {
		// 查询OA_VACATION表的数据
		ProXuanZhiExample example = new ProXuanZhiExample();
		example.createCriteria().andUserIdEqualTo(userId);
		List<ProXuanZhi> vacs = proXuanZhiMapper.selectByExample(example);
		List<ProcessVO> result = new ArrayList<ProcessVO>();
		for (ProXuanZhi vac : vacs) {
			// 查询流程实例
			ProcessInstance pi = this.runtimeService.createProcessInstanceQuery().processInstanceId(vac.getProcInstId())
					.singleResult();
			if (pi != null) {
				// 查询流程参数
				BaseForm var = (BaseForm) this.runtimeService.getVariable(pi.getId(), "arg");
				// 封装界面对象
				ProcessVO vo = new ProcessVO();
				vo.setTitle(var.getTitle());
				vo.setRequestDate(var.getRequestDate());
				vo.setId(pi.getId());
				System.out.println(vo.getTitle());
				System.out.println(vo.getRequestDate());
				result.add(vo);
			}
		}
		return result;
	}

	public InputStream getDiagram(String processInstanceId) {
		// 获取历史流程实例
		HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		// 获取流程图
		BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());

		ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService
				.getProcessDefinition(processInstance.getProcessDefinitionId());

		List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery()
				.processInstanceId(processInstanceId).list();
		// 高亮环节id集合
		List<String> highLightedActivitis = new ArrayList<String>();

		// 高亮线路id集合
		List<String> highLightedFlows = getHighLightedFlows(definitionEntity, highLightedActivitList);

		for (HistoricActivityInstance tempActivity : highLightedActivitList) {
			String activityId = tempActivity.getActivityId();
			highLightedActivitis.add(activityId);
		}

		// 转换为输入流
		InputStream is = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png",
				runtimeService.getActiveActivityIds(processInstanceId));
		InputStream is1 = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png", highLightedActivitis,
				highLightedFlows, "宋体", "宋体", null, 1.0);
		return is1;
	}

	/**
	 * 获取需要高亮的线
	 * 
	 * @param processDefinitionEntity
	 * @param historicActivityInstances
	 * @return
	 */
	private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity,
			List<HistoricActivityInstance> historicActivityInstances) {

		List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
		for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历
			ActivityImpl activityImpl = processDefinitionEntity
					.findActivity(historicActivityInstances.get(i).getActivityId());// 得到节点定义的详细信息
			List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
			ActivityImpl sameActivityImpl1 = processDefinitionEntity
					.findActivity(historicActivityInstances.get(i + 1).getActivityId());
			// 将后面第一个节点放在时间相同节点的集合里
			sameStartTimeNodes.add(sameActivityImpl1);
			for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
				HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 后续第一个节点
				HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 后续第二个节点
				if (activityImpl1.getStartTime().equals(activityImpl2.getStartTime())) {
					// 如果第一个节点和第二个节点开始时间相同保存
					ActivityImpl sameActivityImpl2 = processDefinitionEntity
							.findActivity(activityImpl2.getActivityId());
					sameStartTimeNodes.add(sameActivityImpl2);
				} else {
					// 有不相同跳出循环
					break;
				}
			}
			List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();// 取出节点的所有出去的线
			for (PvmTransition pvmTransition : pvmTransitions) {
				// 对所有的线进行遍历
				ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();
				// 如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示
				if (sameStartTimeNodes.contains(pvmActivityImpl)) {
					highFlows.add(pvmTransition.getId());
				}
			}
		}

		return highFlows;
	}

	// 生成时间
	private String getFormatDate() {
		// 获得当前时间
		DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		// 转换为字符串
		String formatDate = format.format(new Date());
		// 随机生成文件编号
		// int random = new Random().nextInt(10000);
		// return new StringBuffer().append(formatDate).append(
		// random).toString();
		return formatDate;
	}

	/***
	 * 保存文件
	 * 
	 * @param file,newFile
	 * @return
	 */
	private boolean saveFile(MultipartFile file, File newFile) {
		// 判断文件是否为空
		if (!file.isEmpty()) {
			try {

				// 转存文件
				file.transferTo(newFile);
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	/***
	 * List转字符串
	 * 
	 * @param List,char
	 * @return
	 */
	private String listToString(List<String> list, char separator) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			sb.append(list.get(i));
			if (i < list.size() - 1) {
				sb.append(separator);
			}
		}
		return sb.toString();
	}

	// 查询用户的待办任务
	public List<TaskVO> listTasks(String userId) {
		// 查询用户所属的用户组，根据用户I的找到对应的群组
		// Group group =
		// this.identityService.createGroupQuery().groupMember(userId).singleResult();
		// 根据用户组查询任务
		List<Task> tasks = this.taskService.createTaskQuery().taskCandidateUser(userId).list();

		return createTaskVO(tasks);
	}

	// 将Task集合转为TaskVO集合
	private List<TaskVO> createTaskVO(List<Task> tasks) {
		List<TaskVO> result = new ArrayList<TaskVO>();
		for (Task task : tasks) {
			// 查询流程实例
			ProcessInstance pi = this.runtimeService.createProcessInstanceQuery()
					.processInstanceId(task.getProcessInstanceId()).singleResult();
			// 查询流程参数
			Program program = (Program) this.runtimeService.getVariable(pi.getId(), "program");
			// 封装值对象
			TaskVO taskVO = new TaskVO();
			taskVO.setProInstId(program.getProcInstId());
			taskVO.setProName(program.getProName());
			taskVO.setTaskId(task.getId());
			taskVO.setType(program.getType());
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			taskVO.setNumber(task.getPriority());
			taskVO.setTime(simpleDateFormat.format(program.getTime()));
			// 根据用户Id获取用户
			User user = identityService.createUserQuery().userId(program.getUserId()).singleResult();
			taskVO.setUserName(user.getLastName());

			result.add(taskVO);
		}
		return result;
	}

	// 查询用户所受理的全部任务
	public List<TaskVO> listAssigneeTasks(String userId) {
		List<Task> tasks = this.taskService.createTaskQuery().taskAssignee(userId).list();
		// 将Task集合转为TaskVO集合
		return createTaskVO(tasks);
	}

	// 领取任务
	public void claim(String taskId, String userId) {
		this.taskService.claim(taskId, userId);
	}

	// 查询一个任务所在流程的全部评论
	public List<CommentVO> getComments(String taskId) {
		ProcessInstance pi = getProcessInstance(taskId);
		List<CommentVO> result = new ArrayList<CommentVO>();
		List<Comment> comments = this.taskService.getProcessInstanceComments(pi.getId());

		for (Comment c : comments) {
			if (c.getType().equals("comment")) {

				// 查询用户
				User u = this.identityService.createUserQuery().userId(c.getUserId()).singleResult();
				CommentVO vo = new CommentVO();
				vo.setContent(c.getFullMessage());
				vo.setTime(DateUtil.getDateString(c.getTime()));
				vo.setUserName(u.getLastName());
				result.add(vo);
			}
		}
		return result;
	}
	
	//根据piId寻找评论
	// 查询一个任务所在流程的全部评论
		public List<CommentVO> getCommentsByPi(String pi) {
			
			List<CommentVO> result = new ArrayList<CommentVO>();
			List<Comment> comments = this.taskService.getProcessInstanceComments(pi);

			for (Comment c : comments) {
				if (c.getType().equals("comment")) { 

					// 查询用户
					User u = this.identityService.createUserQuery().userId(c.getUserId()).singleResult();
					CommentVO vo = new CommentVO();
					vo.setContent(c.getFullMessage());
					vo.setTime(DateUtil.getDateString(c.getTime()));
					vo.setUserName(u.getLastName());
					result.add(vo);
				}
			}
			return result;
		}
	
	
	
	
	private ProcessInstance getProcessInstance(String taskId) {
		Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
		// 根据任务查询流程实例
		ProcessInstance pi = this.runtimeService.createProcessInstanceQuery()
				.processInstanceId(task.getProcessInstanceId()).singleResult();
		return pi;
	}

	// 查询一个任务所在流程的开始表单信息
	public List<FormField> getFormFields(String taskId) {
		// 根据任务查询流程实例
		ProcessInstance pi = getProcessInstance(taskId);
		// 获取流程参数
		BaseForm baseForm = (BaseForm) this.runtimeService.getVariable(pi.getId(), "arg");
		// 返回表单集合
		List<FormField> formFields = baseForm.getFormFields();
		return formFields;
	}

	@Override
	// 附件查询
	public List<Attachment> getAttachments(String pi) {
		// 根据任务Id查询附件
		List<Attachment> attachments = taskService.getProcessInstanceAttachments(pi);

		return attachments;
	}

	// 审批通过任务
	public void complete(String taskId, String userid) {
		ProcessInstance pi = getProcessInstance(taskId);
		identityService.setAuthenticatedUserId(userid);
		//设置任务持有人
        taskService.setOwner(taskId, userid);  
		// 完成任务
		taskService.complete(taskId);

	}

	// 规划局窗口项目选址意见书完成
	public void complete1(MultipartFile[] file, String taskId, String type, String userid, HttpServletRequest request,
			String programType, String programName, String userID,String content) {

		// int type1 = Integer.parseInt(type);
		ProcessInstance pi = getProcessInstance(taskId);
		identityService.setAuthenticatedUserId(userid);
		
		// 查询第一个任务
		//Task task = this.taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		//设置任务持有人
        taskService.setOwner(taskId, userid);  
		
		// 对表oa_proXuanZhi更新

		// int result = proXuanZhiMapper.updateTypeByProInId(type1,
		// pi.getProcessInstanceId());
		if (type != null) {
			taskService.setVariable(taskId, "arg", type);
		}
		List<String> urls = uploadAttachment(file, request, programType, userID, programName,pi.getId());
		for (int i = 0; i < urls.size(); i++) {
			String filename = file[i].getOriginalFilename();
			String url = urls.get(i);
			// 给流程添加附件
			taskService.createAttachment("departmentAttachment", taskId, pi.getId(), filename, "行政部门出具相关文件", url);
		}
		taskService.addComment(taskId, pi.getId(), content);
		// 完成任务
		taskService.complete(taskId);

	}

	// 启动流程
	@Override
	public ProcessInstance startProcess(MultipartFile[] file, String type, HttpServletRequest request, String userID,
			String programName) {

		// 确定所启动的流程是哪一类
		String processId = "";
		if (type.equals("项目建议书审批")) {
			processId = "ProjectRecommendation";
		}
		if (type.equals("可行性研究报告审批")) {
			processId = "KexingxingYanjiuBaogao";
		}
		if (type.equals("建设项目选址意见书办理")) {
			processId = "ProXuanZhi";
		}
		if (type.equals("办理规划条件")) {
			processId = "GuihuaShejiTiaojian";
		}
		if (type.equals("土地预审意见书")) {
			processId = "YongdiYushenYijianshu";
		}
		if (type.equals("环境影响评价报告审批")) {
			processId = "HuanjingYingxiangPingjiaBaogao";
		}
		if (type.equals("临时使用林地审批")) {
			processId = "LinshiShiyongLindi";
		}
		if (type.equals("建设工程防震设防要求备案")) {
			processId = "KangzhenShefangYaoqiuBeian";
		}
		if (type.equals("人防工程方案报建审批")) {
			processId = "RenfangGongchengFanganBaojian";
		}
		if (type.equals("水工程建设规划同意书审查")) {
			processId = "ShuigongchengJiansheGuihua";
		}
		if (type.equals("可能造成水土流失的生产建设项目水土保持方案审批")) {
			processId = "ShuituBaochiFangan";
		}
		if (type.equals("建设用地规划许可证办理")) {
			processId = "JiansheYongdiGuihuaXukezheng";
		}
		if (type.equals("建设用地审批")) {
			processId = "JiansheYongdi";
		}
		if (type.equals("财政投资项目预算评审")) {
			processId = "CZJ_cztzxmysps";
		}
		if (type.equals("初步设计批复")) {
			processId = "JFJ_cbsjsp";
		}
		if (type.equals("建设工程安全设施设计审查")) {
			processId = "AJJ_aqsssjsc";
		}
		if (type.equals("跨河、穿河、穿堤、临河的工程建设方案审核")) {
			processId = "SWJ_khgcjsfash";
		}
		if (type.equals("河道管理范围内工程建设方案审批")) {
			processId = "SWJ_hdglfwngcjsfnsp";
		}
		if (type.equals("水利建设项目初步设计审批")) {
			processId = "SWJ_sljsxmcbsjsp";
		}
		if (type.equals("建设工程规划许可证办理")) {
			processId = "ZJJ_jsgcghxkzbl";
		}
		if (type.equals("建设项目消防设计备案")) {
			processId = "XFJ_jsxmjgysxfba";
		}
		if (type.equals("人防工程施工图设计文件审核")) {
			processId = "RFB_rfgcsgtsjwjsh";
		}
		if (type.equals("防雷装置设计审核")) {
			processId = "QXJ_flzzsjsh";
		}
		if (type.equals("建设工程节能审查")) {
			processId = "ZJJ_zjj_jngcsjscba";
		}
		if (type.equals("施工项目投招标")) {
			processId = "ZBB_ztbjba";
		}
		if (type.equals("建设项目报建")) {
			processId = "ZJJ_jsxmbj";
		}
		if (type.equals("建设工程质量安全监督申报")) {
			processId = "ZJJ_jsgczlaqjzsb";
		}
		if (type.equals("施工许可证")) {
			processId = "ZJJ_jzgcsgxkz";
		}
		if (type.equals("县道、乡道公路桥梁两侧规定范围内抽取地下水、架设浮桥等活动的许可")) {
			processId = "JTJ_xdxdglqllccqdxsxk";
		}
		if (type.equals("县道、乡道公路施工的许可")) {
			processId = "JTJ_cdcdglsgxk";
		}
		if (type.equals("县道、乡道涉路施工活动的许可")) {
			processId = "JTJ_xdxdslsghdxu";
		}
		if (type.equals("临时占用城市绿化用地审批")) {
			processId = "CGJ_lszycslhydsp";
		}
		if (type.equals("临时占用或挖掘城市道路审批")) {
			processId = "CGJ_lszyhwjcsdlsp";
		}
		if (type.equals("建设项目竣工验收消防备案")) {
			processId = "XFJ_xfsjba";
		}
		if (type.equals("施工质量竣工验收")) {
			processId = "ZJJ_zjj_sgzljgys";
		}
		if (type.equals("建设工程节能专项验收备案")) {
			processId = "ZJJ_zjj_jsgcjnzxba";
		}
		if (type.equals("依法应当编制水土保持方案的生产建设项目中的水土保持设施竣工验收")) {
			processId = "SWJ_jsxmzdstbcssjgys";
		}
		if (type.equals("项目竣工环保验收")) {
			processId = "HBJ_xmjghbys";
		}
		// 查找流程定义
		ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processId)
				.singleResult();

		// 设置申请人受理这个任务
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("userID", userID);
		
		//记录流程启动人
		identityService.setAuthenticatedUserId(userID);
		
		
	
		
		// 启动流程
		ProcessInstance pi = this.runtimeService.startProcessInstanceByKey(pd.getKey(), type,vars);
		
		
		// 查询第一个任务
		Task firstTask = this.taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		
		
		//设置任务持有人
        taskService.setOwner(firstTask.getId(), userID);  

		
		// 记录申请相关信息
		Program program = saveProgram(type, pi.getId(), userID, programName);
		
		// 初始化任务参数
		// Map<String, Object> vars1 = new HashMap<String, Object>();
		// vars1.put("program", program);

		runtimeService.setVariable(pi.getId(), "program", program);

		List<String> urls = uploadAttachment(file, request, type, userID, programName,pi.getId());
		for (int i = 0; i < urls.size(); i++) {

			String filename = file[i].getOriginalFilename();
			String url = urls.get(i);
			// 给流程添加附件
			taskService.createAttachment("userAttachment", firstTask.getId(), pi.getId(), filename, "用户提交的申请材料", url);
		}

		Program test = (Program) runtimeService.getVariable(pi.getId(), "program");
		// 完成任务
		taskService.complete(firstTask.getId(),vars);

		return pi;
	}

	// 将项目申请保存到数据库中
	private Program saveProgram(String type, String piId, String userID, String programName) {
		Program program = new Program();
		program.setProId(UUID.randomUUID().toString());
		program.setProcInstId(piId);
		program.setType(type);
		program.setProName(programName);
		program.setUserId(userID);
		program.setTime(new Date());
		int result = programMapper.insert(program);
		if (result == 1) {
			System.out.println("插入成功");
		}
		return program;
	}

	// 获取用户的全部申请
	public List<TaskVO> getAllApply(String userID) {
		ProgramExample programExample = new ProgramExample();
		programExample.createCriteria().andUserIdEqualTo(userID);
		List<Program> lists = programMapper.selectByExample(programExample);
		List<HistoricProcessInstance> datas = historyService.createHistoricProcessInstanceQuery().startedBy(userID).unfinished().list();
		
		return formatProgram(datas);
	}

	// 根据流程实例获取申请
	public List<Program> getApplyByPi(String Pi) {
		ProgramExample programExample = new ProgramExample();
		programExample.createCriteria().andProcInstIdEqualTo(Pi);
		List<Program> program = programMapper.selectByExample(programExample);
		return program;
	}

	// 将program集合转为TaskVO集合
	public List<TaskVO> formatProgram(List<HistoricProcessInstance> datas) {
		List<TaskVO> result = new ArrayList<TaskVO>();

		for (HistoricProcessInstance data : datas) {
			// 查询流程实例
			// 查询流程参数
			// 封装值对象
			TaskVO taskVO = new TaskVO();
			taskVO.setProInstId(data.getId());
			taskVO.setProName(getProgramByProInstId(data.getId()).getProName());
			taskVO.setTaskId(data.getId());
			taskVO.setType(data.getBusinessKey());
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			// taskVO.setNumber(task.getPriority());
			taskVO.setTime(simpleDateFormat.format(data.getStartTime()));
			// 根据用户Id获取用户
			User user = identityService.createUserQuery().userId(data.getStartUserId()).singleResult();
			taskVO.setUserName(user.getLastName());

			result.add(taskVO);
		}
		return result;
	}
	// 查询已经完成的流程

	@Override
	public List<HistoricProcessInstance> getFinishedFlow( String type) {
		List<HistoricProcessInstance> datas = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(type).finished().list();
		return datas;
	}
//删除文件
	private static boolean deleteFile(String url,HttpServletRequest request) {
		String fileName = request.getSession().getServletContext().getRealPath("upload") ;
				String[] url1 = url.split("/");

		for (int i = 0; i < url1.length; i++) {
			if (!(url1[i].equals("upload"))) {
				fileName = fileName + "/" + url1[i];
			}
		}	
		File file = new File(fileName);
		// 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
		if (file.exists() && file.isFile()) {
			if (file.delete()) {
				System.out.println("删除单个文件" + fileName + "成功！");
				return true;
			} else {
				System.out.println("删除单个文件" + fileName + "失败！");
				return false;
			}
		} else {
			System.out.println("删除单个文件失败：" + fileName + "不存在！");
			return false;
		}
	}
	// 更新文件

	@Override
	public String updateAttachment(MultipartFile[] file,String url,HttpServletRequest request,String taskId) {
		boolean result = deleteFile(url,request);
		String filename = file[0].getOriginalFilename();
		String[] url1 = url.split("/");
		String url11 = url1[0]+"/"+url1[1]+"/"+url1[2]+"/"+url1[3]+"/"+filename;
		if(result == true){
			ProcessInstance pi = getProcessInstance(taskId);

				taskService.createAttachment("userAttachment", taskId, pi.getId(), filename, "用户提交的申请材料", url11);
			
		}
		return null;
	}
	public Group getGroupID(String userId) {
		Group group  =  this.identityService.createGroupQuery().groupMember(userId).singleResult();
		//System.out.println(group.getId());
		return group;
	}

	@Override
	public List<HistoricProcessInstance> getFinishiedFlowByUserId(String userId) {
		List<HistoricProcessInstance> lInstances = historyService.createHistoricProcessInstanceQuery().startedBy(userId).finished().list();
		
		return lInstances;
	}
	//根据用户的ID 查找执行的任务历史
	@Override
	public List<departmentTask> getHistoryOfTask(String userID) {
		List<HistoricTaskInstance> daTaskInstances  = historyService.createHistoricTaskInstanceQuery().taskOwner(userID).finished().list();
		List<departmentTask> lists = new ArrayList<>();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for(int i= 0;i<daTaskInstances.size();i++){
			departmentTask list = new departmentTask();
			list.setEndTime(simpleDateFormat.format(daTaskInstances.get(i).getEndTime()));
			list.setStartTime(simpleDateFormat.format(daTaskInstances.get(i).getStartTime()));
			list.setTaskName(daTaskInstances.get(i).getName());
			Program program = getProgramByProInstId(daTaskInstances.get(i).getProcessInstanceId());
			list.setProName(program.getProName());
			list.setType(program.getType());
			
			lists.add(list);
		}
		return lists;
	}

	@Override
	public Program getProgramByProInstId(String proInstId) {
		
		ProgramExample programExample = new ProgramExample();
		programExample.createCriteria().andProcInstIdEqualTo(proInstId);
		Program program = programMapper.selectByExample(programExample).get(0);
		return program;
	}
	
	//根据Type查找已经结束的全部流程
		@Override
		public List<HistoricProcessInstance> getFinishedFlowByType(String type)  {
			List<HistoricProcessInstance> daTaskInstances  = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(type).finished().list();
			return daTaskInstances;
		}
		
		//根据proInstId查找一个流程的所有的任务
		@Override
		public List<HistoricTaskInstance> getTheDetailOfFlowByProInstId(String proInstId) {
			List<HistoricTaskInstance> daTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(proInstId).list(); 
			return daTaskInstances;
		}
	

}
